#include "pwext.hpp"

namespace ex06ea {
// [[ex06ea]]
// DEBUG descr The synchronous calls in a single-threaded program.
int bar(int arg)
{
	// ...
	// DEBUG {
	return arg+1;
	// DEBUG }
}

void foo()
{
	int a, b;
	// DEBUG {
	b = 10;
	// DEBUG }
	// ...
	a = bar(b);
	// ...
}
// END
};

namespace ex06eb {
// [[ex06eb]]
// DEBUG descr Modification of static data in a single-threaded program.
static int counter = 0;
int bar(int arg)
{
	counter += arg;
	return counter;
}
// END
};

namespace ex06ec {
// [[ex06ec]]
// DEBUG descr Modification of static data in a multithreaded program.
static int counter = 0;
static pw::pmutex barlock;
int bar(int arg)
{
	int c;
	barlock.lock();
	counter += arg;
	c = counter;
	barlock.unlock();
	return c;
}
// END
};

namespace ex06ed {
int bar(int arg);
// [[ex06ed]]
// DEBUG descr States for the repeated calls.
void foo()
{
	int a, b;
	// ...
	a = bar(b); // MSG_CALL_BAR_1
	// ...
	a = bar(b); // MSG_CALL_BAR_2
	// ...
}
// END
};

namespace ex06ee {
int bar(int arg);
// [[ex06ee]]
// DEBUG descr A call done in a loop is still a single state.
void foo()
{
	int a, b, i;
	// ...
	for (i = 0; i < 100; i++) {
		// ...
		a = bar(b); // MSG_CALL_BAR
		// ...
	}
	// ...
}
// END
};

namespace ex06ef {
int bar(int arg);
// [[ex06ef]]
// DEBUG descr A multi-threaded program using locks to achieve atomicity across two calls.
static int uncounter = 0;
int baz(int arg)
{
	uncounter -= arg;
	return uncounter;
}

static pw::pmutex foolock;
void foo()
{
	int a, b, c;
	// ...
	foolock.lock();
	a = bar(b);
	c = baz(b);
	foolock.unlock();
	// ...
}
// END
};

namespace ex06eg {
int bar(int arg);
int baz(int arg);
// [[ex06eg]]
// DEBUG descr A wrapper synchronizing the calls to two functions.
void barbaz(int bararg, int *barret, 
	int bazarg, int *bazret)
{
	*barret = bar(bararg);
	*bazret = baz(bazarg);
}
// END
};

